home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / MacPerl5 / MPUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-14  |  19.6 KB  |  799 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPUtils.c    -
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPUtils.c,v $
  12. Revision 1.2  1994/05/04  02:52:40  neeri
  13. Inline Input.
  14.  
  15. Revision 1.1  1994/02/27  23:02:08  neeri
  16. Initial revision
  17.  
  18. Revision 0.5  1993/08/17  00:00:00  neeri
  19. DoPrefDialog()
  20.  
  21. Revision 0.4  1993/08/15  00:00:00  neeri
  22. DoAbout
  23.  
  24. Revision 0.3  1993/08/14  00:00:00  neeri
  25. Preference file
  26.  
  27. Revision 0.2  1993/05/30  00:00:00  neeri
  28. Support Console Windows
  29.  
  30. Revision 0.1  1993/05/29  00:00:00  neeri
  31. Compiles correctly
  32.  
  33. *********************************************************************/
  34.  
  35. #include <PLStringFuncs.h>
  36. #include <Events.h>
  37. #include <Traps.h>
  38. #include <Dialogs.h>
  39. #include <Fonts.h>
  40. #include <Packages.h>
  41. #include <ToolUtils.h>
  42. #include <AppleEvents.h>
  43. #include <TFileSpec.h>
  44. #include <Folders.h>
  45. #include <Resources.h>
  46. #include <Sound.h>
  47. #include <OSUtils.h>
  48. #include <Files.h>
  49. #include <Lists.h>
  50. #include <Icons.h>
  51. #include <TSMTE.h>
  52. #include <string.h>
  53. #include <GUSI.h>
  54. #include <Desk.h>
  55. #include <ctype.h>
  56. #include <stdio.h>
  57.  
  58. #include "MPUtils.h"
  59. #include "MPWindow.h"
  60. #include "patchlevel.h"
  61.  
  62. /**-----------------------------------------------------------------------
  63.         Name:         ShowError
  64.         Purpose:        Reports an error to the user as both string and number.
  65.     -----------------------------------------------------------------------**/
  66. #if !defined(powerc) && !defined(__powerc)
  67. #pragma segment Utils
  68. #endif
  69.  
  70. pascal void ShowError(Str255 theError, long theErrorCode)
  71. {
  72.     short     alertResult;
  73.     Str255    theString;
  74.  
  75.     if (gAppleEventsImplemented)
  76.         if (AEInteractWithUser(kAEDefaultTimeout, nil,nil))
  77.             return;
  78.         
  79.      SetCursor(&qd.arrow);
  80.      NumToString(theErrorCode, theString);
  81.      ParamText(theError, theString, (StringPtr) "\p", (StringPtr) "\p");
  82.      alertResult = Alert(300, nil);
  83. } /* ShowError */
  84.  
  85. /**-----------------------------------------------------------------------
  86.         Name:         Ours
  87.         Purpose:        Checks the frontmost window belongs to the app.
  88.     -----------------------------------------------------------------------**/
  89. #if !defined(powerc) && !defined(__powerc)
  90. #pragma segment Utils
  91. #endif
  92.  
  93. pascal Boolean Ours(WindowPtr aWindow)
  94. {
  95.     if (aWindow)
  96.         if (((WindowPeek)aWindow)->windowKind == PerlWindowKind)
  97.             return(true);
  98.  
  99.     return(false);
  100. } /* Ours */
  101.  
  102. /**-----------------------------------------------------------------------
  103.         Name:         SetShortMenus
  104.         Purpose:        Cuts the menus down to a minimum - Apple File Edit.
  105.                         Greys out the unavailable options - used when no docs open
  106.     -----------------------------------------------------------------------**/
  107. #if !defined(powerc) && !defined(__powerc)
  108. #pragma segment Utils
  109. #endif
  110.  
  111. pascal void SetShortMenus()
  112. {
  113.     DeleteMenu(windowID);
  114.  
  115.     DrawMenuBar();
  116. }  /* SetShortMenus */
  117.  
  118. /**-----------------------------------------------------------------------
  119.         Name:         SetLongMenus
  120.         Purpose:        Reinstates the full menu bar - called when first document
  121.                     opened.
  122.     -----------------------------------------------------------------------**/
  123. #if !defined(powerc) && !defined(__powerc)
  124. #pragma segment Utils
  125. #endif
  126.  
  127. pascal void SetLongMenus()
  128. {
  129.     InsertMenu(myMenus[windowM], perlID);
  130.  
  131.     DrawMenuBar();
  132. }  /* SetLongMenus */
  133.  
  134. /**-----------------------------------------------------------------------
  135.     Name:       SetEditMenu
  136.     Purpose:    Set the text of the edit menu according to the state of
  137.                      current document.
  138.   -----------------------------------------------------------------------**/
  139.  
  140. #if !defined(powerc) && !defined(__powerc)
  141. #pragma segment Utils
  142. #endif
  143.  
  144. pascal void SetEditMenu(DPtr theDoc)
  145. {
  146.     if (theDoc->kind == kDocumentWindow && theDoc->u.reg.showBorders)
  147.         SetItem(myMenus[editM], cBorders, (StringPtr) "\pHide Borders");
  148.     else
  149.         SetItem(myMenus[editM], cBorders, (StringPtr) "\pShow Borders");
  150. }  /* SetEditMenu */
  151.  
  152. /**-----------------------------------------------------------------------
  153.     Name:       GetTempFSSpec
  154.     Purpose:    Fills newstring create temporary file specification.
  155.   -----------------------------------------------------------------------**/
  156.  
  157. #if !defined(powerc) && !defined(__powerc)
  158. #pragma segment Utils
  159. #endif
  160.  
  161. pascal void GetTempFSSpec(DPtr aDoc, FSSpec * temp)
  162. {
  163.     Special2FSSpec(kTempFileType, aDoc->theFSSpec.vRefNum, 0, temp);
  164. }
  165.  
  166. /**-----------------------------------------------------------------------
  167.     Name:       SetText
  168.     Purpose:    Sets the text of the supplied itemNo in aDialog to
  169.                     theString and select it.
  170.   -----------------------------------------------------------------------**/
  171.  
  172. #if !defined(powerc) && !defined(__powerc)
  173. #pragma segment Utils
  174. #endif
  175.  
  176. pascal void SetText(DialogPtr aDialog, short itemNo, Str255 theString)
  177. {
  178.     Handle      itemHandle;
  179.     Rect        box;
  180.     short       kind;
  181.     TEHandle    theTEHandle;
  182.  
  183.     GetDItem(aDialog, itemNo, &kind, &itemHandle, &box);
  184.     SetIText(itemHandle, theString);
  185.  
  186.     theTEHandle = ((DialogPeek)aDialog)->textH;
  187.  
  188.     /*set all the text to be selected*/
  189.     if (theTEHandle)
  190.         TESetSelect(0, 255, theTEHandle);
  191. }
  192.  
  193. /**-----------------------------------------------------------------------
  194.     Name:       RetrieveText
  195.     Purpose:    Returns the text of anItem in aDialog in aString.
  196.   -----------------------------------------------------------------------**/
  197.  
  198. #if !defined(powerc) && !defined(__powerc)
  199. #pragma segment Utils
  200. #endif
  201.  
  202. pascal void RetrieveText(DialogPtr aDialog, short anItem, Str255 aString)
  203. {
  204.     short      kind;
  205.     Rect       box;
  206.     Handle     itemHandle;
  207.  
  208.     GetDItem(aDialog, anItem, &kind, &itemHandle, &box);
  209.     GetIText(itemHandle, aString);
  210. }
  211.  
  212. /**-----------------------------------------------------------------------
  213.     Name:      DrawDefaultOutline
  214.     Purpose:   Draws an outline around theItem.
  215.                     Called as a useritem Proc by the dialog manager.
  216.                     To use place a useritem over the default item in the
  217.                     dialog and install the address of this proc as the item
  218.                     handle.
  219.   -----------------------------------------------------------------------**/
  220.  
  221. #if !defined(powerc) && !defined(__powerc)
  222. #pragma segment Utils
  223. #endif
  224.  
  225. pascal void DrawDefaultOutline(DialogPtr theDialog, short theItem)
  226. {
  227.     short       kind;
  228.     Handle      itemHandle;
  229.     Rect        box;
  230.  
  231.     GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  232.     PenSize(3, 3);
  233.     InsetRect(&box, -4, -4);
  234.     FrameRoundRect(&box, 16, 16);
  235.     PenNormal();
  236. }  /* DrawDefaultOutline */
  237.  
  238. #if USESROUTINEDESCRIPTORS
  239. RoutineDescriptor    uDrawDefaultOutline = 
  240.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawDefaultOutline);
  241. #endif
  242.  
  243. /**-----------------------------------------------------------------------
  244.     Name:       AdornDefaultButton
  245.     Purpose:    Installs DrawDefaultOutline as the useritem proc
  246.                      for the given item.
  247. -----------------------------------------------------------------------**/
  248.  
  249. #if !defined(powerc) && !defined(__powerc)
  250. #pragma segment Utils
  251. #endif
  252.  
  253. pascal void AdornDefaultButton(DialogPtr theDialog,short theItem)
  254. {
  255.     short        kind;
  256.     Handle    itemHandle;
  257.      Rect        box;
  258.  
  259.     GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  260.     SetDItem(theDialog, theItem, kind, (Handle)&uDrawDefaultOutline, &box);
  261. }
  262.  
  263. pascal void GetRectOfDialogItem(DialogPtr theDialog, short theItem, Rect *theRect)
  264. {
  265.     short       kind;
  266.     Handle      itemHandle;
  267.  
  268.     GetDItem(theDialog, theItem, &kind, &itemHandle, theRect);
  269. }
  270.  
  271. /**------  FeatureIsImplemented    ------------**/
  272. /*    This is called to use Gestalt to determine if a feature is implemented.
  273.      This applies to only those referenced by OSType    */
  274.  
  275. #if !defined(powerc) && !defined(__powerc)
  276. #pragma segment Utils
  277. #endif
  278.  
  279. pascal Boolean FeatureIsImplemented(OSType theFeature, short theTestBit)
  280. {
  281.      long      result;
  282.  
  283.     return !Gestalt(theFeature, &result) && (result & (1 << theTestBit));
  284. }
  285.  
  286. #if !defined(powerc) && !defined(__powerc)
  287. #pragma segment Utils
  288. #endif
  289.  
  290. pascal Boolean CheckEnvironment()
  291. {
  292.     long result;
  293.     
  294.     /*check for the AppleEvents manager - we certainly can't work without it*/
  295.  
  296.     gAppleEventsImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr, gestaltAppleEventsPresent);
  297.  
  298.     /*first check if the Edition Manager is present*/
  299.  
  300.     gEditionManagerImplemented = FeatureIsImplemented(gestaltEditionMgrAttr, gestaltEditionMgrPresent);
  301.  
  302.     /*and for good measure- the Alias manager*/
  303.  
  304.     gAliasManagerImplemented  = FeatureIsImplemented(gestaltAliasMgrAttr, gestaltAliasMgrPresent);
  305.  
  306.     /*check if recording is implemented*/
  307.  
  308.     gRecordingImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr,1);
  309.  
  310.     /*check for the Outline fonts*/
  311.  
  312.     gOutlineFontsImplemented  = FeatureIsImplemented(gestaltFontMgrAttr, gestaltOutlineFonts);
  313.  
  314.     /* check for Text Services and TSMTE */
  315.     gTextServicesImplemented = !Gestalt(gestaltTSMgrVersion, &result) && (result > 0);
  316.     gTSMTEImplemented    = FeatureIsImplemented(gestaltTSMTEAttr, gestaltTSMTEPresent);
  317.  
  318.     return     gEditionManagerImplemented &&
  319.                 gAliasManagerImplemented   &&
  320.                 gAppleEventsImplemented    &&
  321.                 gOutlineFontsImplemented;
  322. }  /* CheckEnvironment */
  323.  
  324. /*
  325.     DoPageSetup returns true if the page setup of the document is altered
  326. */
  327.  
  328. pascal Boolean DoPageSetup(DPtr theDoc)
  329. {
  330.     if (theDoc) {
  331.         Boolean result;
  332.  
  333.         PrOpen();
  334.         result =  PrStlDialog(theDoc->thePrintSetup);
  335.         PrClose();
  336.  
  337.         return(result);
  338.     }
  339. }  /* DoPageSetup */
  340.  
  341. /*
  342.     Name:    CtrlKeyPressed
  343.     Purpose: Returns true if control key pressed during event
  344. */
  345. pascal Boolean CtrlKeyPressed(const EventRecord *theEvent)
  346. {
  347.     return theEvent->modifiers & controlKey;
  348. }
  349.  
  350. /*
  351.     Name:    OptionKeyPressed
  352.     Purpose: Returns true if option key pressed during event
  353. */
  354. pascal Boolean OptionKeyPressed(const EventRecord *theEvent)
  355. {
  356.     return theEvent->modifiers & optionKey;
  357. }
  358.  
  359. pascal void DrawVersion(DialogPtr dlg, short item)
  360. {
  361.     VersRecHndl    vers;
  362.     short         resFile;
  363.     short            base;
  364.     Handle        h;
  365.     Rect            r;
  366.     FontInfo        info;
  367.     Str15            patchlevel;
  368.  
  369.     GetDItem(dlg, item, &base, &h, &r);
  370.     SetPort(dlg);
  371.     TextFont(1);
  372.     TextSize(10);
  373.     GetFontInfo(&info);
  374.     
  375.     base = r.top+2+info.ascent;
  376.     MoveTo(r.left+2, base);
  377.     DrawString((StringPtr) "\pVersion");
  378.     MoveTo((r.left+r.right) >> 1, r.top+2+info.ascent);
  379.  
  380.     resFile = CurResFile();
  381.     UseResFile(gAppFile);
  382.     vers = (VersRecHndl) Get1Resource('vers', 1);
  383.     HLock((Handle) vers);
  384.     DrawString((*vers)->shortVersion);
  385.     ReleaseResource((Handle) vers);
  386.     UseResFile(resFile);
  387. }
  388.  
  389. #if USESROUTINEDESCRIPTORS
  390. RoutineDescriptor    uDrawVersion = 
  391.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawVersion);
  392. #else
  393. #define uDrawVersion *(UserItemUPP)&DrawVersion
  394. #endif
  395.  
  396. static ListHandle    CreditList;
  397.  
  398. pascal void DrawCredits(DialogPtr dlg, short item)
  399. {
  400. #if !defined(powerc) && !defined(__powerc)
  401. #pragma unused(item)
  402. #endif
  403.     Rect    r;
  404.     
  405.     TextFont(1);
  406.     TextSize(9);
  407.     r = (*CreditList)->rView;
  408.     MoveTo(r.left + 4, r.top - 8);
  409.     TextFace(bold);
  410.     DrawString("\pThanks to:");
  411.     TextFace(normal);
  412.     LUpdate(dlg->visRgn, CreditList);
  413. }
  414.  
  415. #if USESROUTINEDESCRIPTORS
  416. RoutineDescriptor    uDrawCredits = 
  417.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawCredits);
  418. #else
  419. #define uDrawCredits *(UserItemUPP)&DrawCredits
  420. #endif
  421.  
  422. pascal void DoAbout(Boolean easter)
  423. {
  424.     DialogPtr        dlg;
  425.     WindowPtr        win;
  426.     short                kind;
  427.     short                count;
  428.     Handle            hdl;
  429.     Handle            sound;
  430.     SndChannelPtr     channel = nil;
  431.     long                now;
  432.     long                nextAction;
  433.     Point             cell;
  434.     Rect                bounds;
  435.     Rect                dbounds;
  436.     Str255            string;
  437.     EventRecord     ev;
  438.     
  439.     SetCursor(&qd.arrow);
  440.     
  441.     dlg     = GetNewDialog(AboutDialog, nil, (WindowPtr) -1);
  442.     sound = GetResource('snd ', AlertSoundID+easter);
  443.     hdl     = GetResource('STR#', CreditID);
  444.     count    = **(short **) hdl;
  445.  
  446.     GetDItem(dlg, ad_PatchLevel, &kind, &hdl, &bounds);
  447.     SetDItem(dlg, ad_PatchLevel, kind, (Handle) &uDrawVersion, &bounds);
  448.     GetDItem(dlg, ad_Credits, &kind, &hdl, &bounds);
  449.     SetDItem(dlg, ad_Credits, kind, (Handle) &uDrawCredits, &bounds);
  450.  
  451.     bounds.top   += 20;
  452.  
  453.     SetPort(dlg);
  454.     TextFont(1);
  455.     TextSize(9);
  456.     SetPt(&cell, bounds.right - bounds.left, 12);
  457.     SetRect(&dbounds, 0, 0, 1, count);
  458.     CreditList = LNew(&bounds, &dbounds, cell, 0, dlg, false, false, false, false);
  459.     
  460.     SetPt(&cell, 0, 0);
  461.     for (; cell.v < count; ++cell.v) {
  462.         GetIndString(string, CreditID, cell.v+1);
  463.         LSetCell((Ptr)(string+1), *string, cell, CreditList);
  464.     }
  465.     LDoDraw(true, CreditList);
  466.     
  467.     HideDialogItem(dlg, ad_Version);
  468.     ShowWindow(dlg);
  469.     DrawDialog(dlg);
  470.     
  471.     nextAction = TickCount()+30;
  472.     SetPt(&cell, 0, count-1);
  473.     
  474.     while (dlg) {
  475.         if (TickCount() > nextAction) {
  476.             if (sound) {
  477.                 RgnHandle versRgn = NewRgn();
  478.  
  479.                 HLock(sound);
  480.                 if (!SndNewChannel(&channel, sampledSynth, initMono, nil))
  481.                     SndPlay(channel, (SndListHandle) sound, true);
  482.                     
  483.                 ShowDialogItem(dlg, ad_Version);
  484.                 GetDItem(dlg, ad_Version, &kind, &hdl, &bounds);
  485.                 RectRgn(versRgn, &bounds);
  486.                 UpdateDialog(dlg, versRgn);
  487.                 DisposeRgn(versRgn);
  488.                 
  489.                 if (channel)
  490.                     SndDisposeChannel(channel, false);
  491.                     
  492.                 ReleaseResource(sound);
  493.                 sound = nil;
  494.             } else {
  495.                 LSetSelect(false, cell, CreditList);
  496.                 cell.v = (cell.v+1) % count;
  497.                 LSetSelect(true, cell, CreditList);
  498.                 LAutoScroll(CreditList);
  499.             }
  500.             nextAction += 45;
  501.         }
  502.         
  503.         if (WaitNextEvent(mDownMask+keyDownMask+activMask+updateMask+osMask, &ev, 1, nil))
  504.             switch (ev.what) {
  505.             case activateEvt:
  506.                 if ((WindowPtr) ev.message != dlg)
  507.                     DoActivate((WindowPtr)ev.message, (ev.modifiers & activeFlag) != 0);
  508.                 else 
  509.                     LActivate(ev.modifiers & activeFlag, CreditList);
  510.     
  511.                 break;
  512.     
  513.             case updateEvt:
  514.                 win = (WindowPtr) ev.message;
  515.                 if (win == dlg) {
  516.                     BeginUpdate(dlg);
  517.                     UpdateDialog(dlg, dlg->visRgn);
  518.                     EndUpdate(dlg);
  519.                 } else
  520.                     DoUpdate(DPtrFromWindowPtr(win), win);
  521.                 break;
  522.     
  523.             case kOSEvent:
  524.                 switch (ev.message & osEvtMessageMask) { /*high byte of message*/
  525.                 case 0x01000000:
  526.                         gInBackground = ((ev.message & resumeFlag) == 0);
  527.                 }
  528.                 if (!gInBackground)
  529.                     break;
  530.             default:
  531.                 DisposeDialog(dlg);
  532.                 
  533.                 dlg = nil;
  534.                 break;
  535.             }
  536.     }
  537. }
  538.  
  539. static void CenterWindow(DialogPtr dlg)
  540. {
  541.     Rect    *        screen;
  542.     short            hPos;
  543.     short            vPos;
  544.     
  545.     screen    =    &qd.screenBits.bounds;
  546.     hPos    =    screen->right+screen->left-dlg->portRect.right >> 1;
  547.     vPos    =    (screen->bottom-screen->top-dlg->portRect.bottom)/3;
  548.     vPos    +=    screen->top;
  549.     MoveWindow(dlg, hPos, vPos, true);
  550. }    
  551.  
  552. pascal void Separator(DialogPtr dlg, short item)
  553. {
  554.     short        kind;
  555.     Handle    h;
  556.     Rect        r;
  557.     
  558.     PenPat(&qd.gray);
  559.     GetDItem(dlg, item, &kind, &h, &r);
  560.     FrameRect(&r);
  561.     PenPat(&qd.black);
  562. }
  563.  
  564. #if USESROUTINEDESCRIPTORS
  565. RoutineDescriptor    uSeparator = 
  566.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, Separator);
  567. #endif
  568.  
  569. static DPtr        Documents[50];
  570. static short    DocCount = 0;
  571.  
  572. pascal void RegisterDocument(DPtr doc)
  573. {
  574.     Documents[DocCount++] = doc;
  575. }
  576.  
  577. pascal void UnregisterDocument(DPtr doc)
  578. {
  579.     short    i,j;
  580.     
  581.     for (i = 0, j = 0; i < DocCount; ++i)
  582.         if (Documents[i] != doc)
  583.             Documents[j++] = Documents[i];
  584.     
  585.     DocCount = j;
  586. }
  587.  
  588. pascal void SetupWindowMenu()
  589. {
  590.     short            i;
  591.     short            item = 0;
  592.     WindowPtr    front;
  593.      WindowPeek    aWindow;
  594.     WindowPeek    nextWindow;
  595.     MenuHandle    menu;
  596.     Str255        name;
  597.     int             needsSeparator = 0;
  598.     
  599.     DisposeMenu(myMenus[windowM]);
  600.     menu = myMenus[windowM]    = GetMenu(windowID);
  601.     
  602.     front = FrontWindow();
  603.     
  604.     for (i = 0; i < DocCount; ++i)
  605.         if (Documents[i]->kind != kDocumentWindow) {
  606.             AppendMenu(menu, (StringPtr) "\px");
  607.             GetWTitle(Documents[i]->theWindow, name);
  608.             SetMenuItemText(menu, ++item, name);
  609.             
  610.             if (!((WindowPeek) Documents[i]->theWindow)->visible)
  611.                 SetItemStyle(menu, item, italic);
  612.             else if (Documents[i]->theWindow == front)
  613.                 SetItemMark(menu, item, checkMark);
  614.             
  615.             EnableItem(menu, item);
  616.             needsSeparator = 1;
  617.         }
  618.     
  619.     for (i = 0; i < DocCount; ++i)
  620.         if (Documents[i]->kind == kDocumentWindow) {
  621.             if (needsSeparator && needsSeparator < 2) {
  622.                 AppendMenu(menu, (StringPtr) "\p-(");
  623.                 ++item;
  624.             }
  625.             
  626.             AppendMenu(menu, (StringPtr) "\px");
  627.             GetWTitle(Documents[i]->theWindow, name);
  628.             SetMenuItemText(menu, ++item, name);
  629.             
  630.             if (!((WindowPeek) Documents[i]->theWindow)->visible)
  631.                 SetItemStyle(menu, item, Documents[i]->dirty ? underline + italic : italic);
  632.             else {
  633.                 if (Documents[i]->dirty)
  634.                     SetItemStyle(menu, item, underline);
  635.                 if (Documents[i]->theWindow == front)
  636.                     SetItemMark(menu, item, checkMark);
  637.             }
  638.             
  639.             EnableItem(menu, item);
  640.             needsSeparator = 2;
  641.         }
  642.     
  643.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  644.         nextWindow = aWindow->nextWindow;
  645.         if (aWindow->visible && !Ours((WindowPtr) aWindow)) {
  646.             if (needsSeparator && needsSeparator < 3) {
  647.                 AppendMenu(menu, (StringPtr) "\p-(");
  648.                 ++item;
  649.             }
  650.             
  651.             AppendMenu(menu, (StringPtr) "\px");
  652.             GetWTitle((WindowPtr) aWindow, name);
  653.             SetMenuItemText(menu, ++item, name);
  654.             
  655.             if ((WindowPtr) aWindow == front)
  656.                 SetItemMark(menu, item, checkMark);
  657.             
  658.             EnableItem(menu, item);
  659.             needsSeparator = 3;
  660.         }
  661.     }
  662. }
  663.  
  664. static void AnointWindow(WindowPtr win)
  665. {
  666.     if (!((WindowPeek) win)->visible)
  667.         ShowWindow(win);
  668.     SelectWindow(win);
  669. }
  670.  
  671. pascal void DoSelectWindow(short item)
  672. {
  673.     short            i;
  674.      WindowPeek    aWindow;
  675.     WindowPeek    nextWindow;
  676.     MenuHandle    menu;
  677.     int             needsSeparator = 0;
  678.     
  679.     menu = myMenus[windowM];
  680.     
  681.     for (i = 0; i < DocCount; ++i)
  682.         if (Documents[i]->kind != kDocumentWindow) {
  683.             if (!--item) {
  684.                 AnointWindow(Documents[i]->theWindow);
  685.                 
  686.                 return;
  687.             }
  688.             needsSeparator = 1;
  689.         }
  690.     
  691.     for (i = 0; i < DocCount; ++i)
  692.         if (Documents[i]->kind == kDocumentWindow) {
  693.             if (needsSeparator && needsSeparator < 2) {
  694.                 --item;
  695.             }
  696.             
  697.             if (!--item) {
  698.                 AnointWindow(Documents[i]->theWindow);
  699.                 
  700.                 return;
  701.             }
  702.             
  703.             needsSeparator = 2;
  704.         }
  705.     
  706.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  707.         nextWindow = aWindow->nextWindow;
  708.         if (aWindow->visible && !Ours((WindowPtr) aWindow)) {
  709.             if (needsSeparator && needsSeparator < 3) {
  710.                 --item;
  711.             }
  712.             
  713.             if (!--item) {
  714.                 AnointWindow((WindowPtr) aWindow);
  715.                 
  716.                 return;
  717.             }
  718.             
  719.             needsSeparator = 3;
  720.         }
  721.     }
  722. }
  723.  
  724. /* Borrowed from tech note 263 */
  725.  
  726. #define kKosherModifiers    0x0E00        // We keep only option & shift
  727. #define kMaskVirtualKey     0x0000FF00     // get virtual key from event message
  728.                                            // for KeyTrans
  729. #define kUpKeyMask          0x0080
  730. #define kShiftWord          8              // we shift the virtual key to mask it
  731.                                            // into the keyCode for KeyTrans
  732. #define kMaskASCII1         0x00FF0000     // get the key out of the ASCII1 byte
  733. #define kMaskASCII2         0x000000FF     // get the key out of the ASCII2 byte
  734.  
  735. pascal Boolean WeirdChar(const EventRecord * ev, short modifiers, char ch)
  736. {
  737.       short            keyCode;
  738.       long             virtualKey, keyInfo, lowChar, highChar, keyCId;
  739.     unsigned long    state;
  740.       Handle           hKCHR;
  741.     Ptr                 KCHRPtr;
  742.  
  743.     if ((ev->what == keyDown) || (ev->what == autoKey)) {
  744.  
  745.         // see if the command key is down.  If it is, find out the ASCII
  746.         // equivalent for the accompanying key.
  747.  
  748.         if ((ev->modifiers & 0xFF00) == modifiers) {
  749.  
  750.             virtualKey     = (ev->message & kMaskVirtualKey) >> kShiftWord;
  751.             keyCode          = (ev->modifiers & kKosherModifiers & ~modifiers) | virtualKey;
  752.             state           = 0;
  753.  
  754.             hKCHR            = nil;  /* set this to nil before starting */
  755.              KCHRPtr         = (Ptr)GetEnvirons(smKCHRCache);
  756.  
  757.             if ( !KCHRPtr ) {
  758.                 keyCId     =    GetScript((short) GetEnvirons(smKeyScript), smScriptKeys);
  759.                 hKCHR        =    GetResource('KCHR', (short) keyCId);
  760.                 KCHRPtr    = *hKCHR;
  761.             }
  762.  
  763.             if (KCHRPtr) {
  764.                 keyInfo = KeyTrans(KCHRPtr, keyCode, &state);
  765.                 if (hKCHR)
  766.                     ReleaseResource(hKCHR);
  767.             } else
  768.                 keyInfo = ev->message;
  769.  
  770.             lowChar =  keyInfo &  kMaskASCII2;
  771.             highChar = (keyInfo & kMaskASCII1) >> 16;
  772.             if (lowChar == ch || highChar == ch)
  773.                 return true;
  774.  
  775.         }  // end the command key is down
  776.     }  // end key down event
  777.  
  778.     return false;
  779. }
  780.  
  781.  
  782. pascal Boolean SameFSSpec(FSSpec * one, FSSpec * other)
  783. {
  784.     return     one->vRefNum    ==        other->vRefNum 
  785.         &&        one->parID        ==        other->parID
  786.         &&     EqualString(one->name, other->name, false, true);
  787. }
  788.  
  789. void RemoveConsole()
  790. {
  791. }
  792.  
  793. int faccess()
  794. {
  795.     return -1;
  796. }
  797.  
  798. int StandAlone = 1;
  799.